#pragma once

#include <unistd.h>
#include <pthread.h>
#include <vector>
#include <string>
#include "EventLoop.hpp"
#include "Log.hpp"

class WorkerThread
{
public:
    WorkerThread(int index = 0 /* 线程在线程池中的编号 */)
    {
        _name = "SubThread-" + std::to_string(index);
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }
    // 主线程调用
    void Run()
    {
        // 创建子线程
        pthread_create(&_tid, nullptr, Worker, this);
        pthread_mutex_lock(&_mutex);
        // 等待子线程创建完EventLoop实例
        while (_evLoop == nullptr)
        {
            pthread_cond_wait(&_cond, &_mutex);
        }
        pthread_mutex_unlock(&_mutex);
    }
    EventLoop *GetEventLoop()
    {
        return _evLoop;
    }
    ~WorkerThread()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
        if (_evLoop)
            delete _evLoop;
    }

private:
    static void *Worker(void *arg)
    {
        WorkerThread *worker = static_cast<WorkerThread *>(arg);
        pthread_mutex_lock(&worker->_mutex);
        worker->_evLoop = new EventLoop(worker->_name.c_str());
        pthread_mutex_unlock(&worker->_mutex);
        // 唤醒主线程
        pthread_cond_signal(&worker->_cond);
        // 运行反应堆模型
        // LOG(INFO) << worker->_name << ": run\n";

        worker->_evLoop->run();
        return nullptr;
    }

private:
    pthread_t _tid;               // 线程id
    std::string _name;            // 名字
    pthread_mutex_t _mutex;       // 互斥锁
    pthread_cond_t _cond;         // 条件变量
    EventLoop *_evLoop = nullptr; // EventLoop实例
};

class ThreadPool
{
public:
    ThreadPool(int threadNum, EventLoop *evLoop)
        : _threadNum(threadNum),
          _mainLoop(evLoop),
          _threadIDs(_threadNum, nullptr)
    {
    }
    void Run()
    {
        if (pthread_self() != _mainLoop->_threadID)
        {
            exit(-1);
        }
        _isStart = true;
        for (int i = 0; i < _threadNum; ++i)
        {
            // LOG(INFO) << pthread_self() << ": create thread\n";
            WorkerThread *worker = new WorkerThread(i + 1);
            _threadIDs[i] = worker;
            worker->Run();
        }
    }
    // 取出子线程反应堆实例
    EventLoop *GetEventLoop()
    {
        if (!_isStart)
            return nullptr;
        if (pthread_self() != _mainLoop->_threadID)
        {
            exit(-1);
        }
        EventLoop *evLoop = _mainLoop;
        if (_threadNum > 0)
        {
            evLoop = _threadIDs[_index++]->GetEventLoop();
            _index %= _threadNum;
        }
        return evLoop;
    }

private:
    bool _isStart = false;                  // 停止标志位
    int _index = 0;                         // 当前访问线程编号
    int _threadNum = 0;                     // 线程数
    EventLoop *_mainLoop = nullptr;         // 主线程反映堆模型
    std::vector<WorkerThread *> _threadIDs; // 执行任务线程ID
};